import ProxyManager from "./ProxyManager.js";
import { CONFIG_DEFAULT_IP, CONFIG_DEFAULT_PORT } from "../constants.js";
import {
	$,
	generateNaoId,
	toggleEle,
	debounce,
	parsePasteText,
} from "../utils.js";

// 暂时禁用这三个协议
const protocolList = Object.values(chrome.proxy.Scheme).filter(
	(protocol) =>
		protocol !== "quic" && protocol !== "socks4" && protocol !== "socks5"
);
const proxyManager = new ProxyManager();
const proxyTableBody = $("#proxy-table-body");

const insertAndEnableBtn = $("#insert-and-enable-btn");
const insertBtn = $("#insert-btn");
const cancelBtn = $("#cancel-btn");

const popupWrapper = $("#popup-wrapper");
const popupSelect = $("#popup-select");
const ipInput = $("#ip-input");
const portInput = $("#port-input");

// 防抖函数
const ipInputEventHandler = debounce((input, id) => {
	let ip = input.innerHTML;
	
	if (!ip || !ip.trim()) {
		ip = CONFIG_DEFAULT_IP;
		input.innerHTML = ip;
	}

	proxyManager.updateProxy(id, { ip: ip.trim() });
}, 1500);

const portInputEventHandler = debounce((input, id) => {
	let port = input.innerHTML;

	if (!port || !port.trim()) {
		port = CONFIG_DEFAULT_PORT;
		input.innerHTML = port;
	}

	port = parseInt(port);

	proxyManager.updateProxy(id, { port });
}, 1500);

render();
loadPopupSelect();

insertAndEnableBtn.onclick = () => {
	saveForm(true);
};

insertBtn.onclick = () => {
	saveForm();
};

cancelBtn.onclick = () => {
	clearForm();
};

function render() {
	proxyTableBody.innerHTML = "";
	proxyManager.getDataList().then(({ dataList }) => {
		if (!dataList) {
			return;
		}

		dataList.forEach(({ id, protocol, ip, port, isUsed }) => {
			const tr = document.createElement("tr");

			// protocol
			const protocolTd = document.createElement("td");
			const protocolSelectDiv = document.createElement("div");
			const optionsDiv = document.createElement("div");

			protocolTd.className = "protocol";
			protocolSelectDiv.innerHTML = protocol;
			protocolSelectDiv.className = "protocol-select";
			optionsDiv.className = "options";
			loadOptions(optionsDiv, id);
			protocolTd.append(protocolSelectDiv, optionsDiv);

			// ip
			const ipTd = document.createElement("td");
			ipTd.innerHTML = ip;
			ipTd.className = "ip";
			ipTd.contentEditable = true;
			ipTd.onkeydown = function () {
				ipInputEventHandler(this, id);
			};
			parsePasteText(ipTd);

			// port
			const portTd = document.createElement("td");
			portTd.innerHTML = port;
			portTd.className = "port";
			portTd.contentEditable = true;
			portTd.onkeydown = function () {
				portInputEventHandler(this, id);
			};
			parsePasteText(portTd);

			// operation
			const operationTd = document.createElement("td");
			const deleteBtn = document.createElement("button");

			operationTd.className = "operation";
			deleteBtn.innerHTML = "删 除";
			deleteBtn.className = "delete";
			deleteBtn.onclick = function () {
				proxyManager.deleteProxy(id);
				render();
			};

			if (!isUsed) {
				const enableBtn = document.createElement("button");
				enableBtn.className = "enable";
				enableBtn.innerHTML = "启 用";
				enableBtn.onclick = function () {
					proxyManager.enableProxy(id);
					render();
				};
				operationTd.append(enableBtn);
			}
			operationTd.append(deleteBtn);

			tr.append(protocolTd, ipTd, portTd, operationTd);
			proxyTableBody.append(tr);
		});
	});
}

function saveForm(isUsed = false) {
	const protocol = popupSelect.innerHTML.trim();
	const ip = ipInput.value;
	const port = portInput.value;

	if (!ip) {
		alert("IP地址错误！");
		return;
	}

	if (!port) {
		alert("端口号错误！");
		return;
	}

	const proxyObj = {
		id: generateNaoId(),
		protocol,
		ip,
		port: parseInt(port),
		isUsed,
	};

	proxyManager.insertProxy(proxyObj);

	if (isUsed) {
		proxyManager.enableProxy(proxyObj.id);
	}

	clearForm();
	render();
}

function clearForm() {
	resetPopupSelect();
	ipInput.value = "";
	portInput.value = "";
	toggleEle(popupWrapper);
}

function loadPopupSelect() {
	loadOptions(popupSelect.nextElementSibling);
	resetPopupSelect();
}

function resetPopupSelect() {
	const firstOption = popupSelect.nextElementSibling.firstElementChild;
	popupSelect.innerHTML = firstOption.innerHTML;
}

function loadOptions(optionsDiv, id) {
	protocolList.forEach((protocol) => {
		const optionDiv = document.createElement("div");
		optionDiv.innerHTML = protocol;
		optionDiv.className = "option";

		optionDiv.onclick = function () {
			optionClick(this, id);
		};

		optionsDiv.append(optionDiv);
	});
}

/**
 * @param {HTMLElement} option
 */
function optionClick(option, id) {
	const protocol = option.innerHTML.trim();
	const select = option.parentElement.previousElementSibling;
	select.innerHTML = protocol;

	if (!id) {
		return;
	}

	proxyManager.updateProxy(id, { protocol });
}
